-
Notifications
You must be signed in to change notification settings - Fork 1k
machine/attiny85: add USI-based SPI support #5181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jespino
wants to merge
8
commits into
tinygo-org:dev
Choose a base branch
from
jespino:attiny85-spi-support
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+171
−2
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implement SPI communication for ATTiny85 using the USI (Universal Serial Interface) hardware in three-wire mode. The ATTiny85 lacks dedicated SPI hardware but can emulate SPI using the USI module with software clock strobing. Implementation details: - Configure USI in three-wire mode for SPI operation - Use clock strobing technique to shift data in/out - Pin mapping: PB2 (SCK), PB1 (MOSI/DO), PB0 (MISO/DI) - Support both Transfer() and Tx() methods The implementation uses the USI control register (USICR) to toggle the clock pin, which triggers automatic bit shifting in hardware. This is more efficient than pure software bit-banging. Current limitations: - Frequency configuration not yet implemented (runs at max software speed) - Only SPI Mode 0 (CPOL=0, CPHA=0) supported - Only MSB-first bit order supported Co-Authored-By: Claude Sonnet 4.5 <[email protected]> Co-authored-by: Ona <[email protected]>
14a2504 to
d88634f
Compare
Add software-based frequency control for USI SPI. The ATtiny85 USI lacks hardware prescalers, so frequency is controlled via delay loops between clock toggles. - Calculate delay cycles based on requested frequency and CPU clock - Fast path (no delay) when frequency is 0 or max speed requested - Delay loop uses nop instructions for timing control Co-authored-by: Ona <[email protected]>
Contributor
Author
|
I have a problem about the Modes here, I can try to implement them but I don't have SPI devices with other modes, also, I don't have an SPI device for reading. Maybe I need somebody helping me with that. |
Add support for all 4 SPI modes (Mode 0-3) using USI hardware: - Mode 0 (CPOL=0, CPHA=0): Clock idle low, sample on rising edge - Mode 1 (CPOL=0, CPHA=1): Clock idle low, sample on falling edge - Mode 2 (CPOL=1, CPHA=0): Clock idle high, sample on falling edge - Mode 3 (CPOL=1, CPHA=1): Clock idle high, sample on rising edge CPOL is controlled by setting the clock pin idle state. CPHA is controlled via the USICS0 bit in USICR. Co-authored-by: Ona <[email protected]>
Add software-based LSB-first support for USI SPI. The USI hardware only supports MSB-first, so bit reversal is done in software before sending and after receiving. Uses an efficient parallel bit swap algorithm (3 operations) to reverse the byte. Co-authored-by: Ona <[email protected]>
Test the USI-based SPI implementation for ATtiny85/digispark. Co-authored-by: Ona <[email protected]>
Reduce SPI struct from ~14 bytes to 1 byte to fit in ATtiny85's limited 512 bytes of RAM. Changes: - Remove register pointers (use avr.USIDR/USISR/USICR directly) - Remove pin fields (USI pins are fixed: PB0/PB1/PB2) - Remove CS pin management (user must handle CS) - Remove frequency control (runs at max speed) - Remove LSBFirst support The SPI struct now only stores the USICR configuration byte. Co-authored-by: Ona <[email protected]>
This reverts commit 387ccad. Co-authored-by: Ona <[email protected]>
Remove unnecessary fields from SPI struct while keeping all functionality: - Remove register pointers (use avr.USIDR/USISR/USICR directly) - Remove pin fields (USI pins are fixed: PB0/PB1/PB2) - Remove CS pin (user must manage it, standard practice) Kept functional fields: - delayCycles for frequency control - usicrValue for SPI mode support - lsbFirst for bit order support SPI struct reduced from 14 bytes to 4 bytes. Co-authored-by: Ona <[email protected]>
Member
|
I see the LED flickering but it does not seem to be communicating with my MCP3008. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implement SPI communication for ATtiny85 using the USI (Universal Serial Interface) hardware in three-wire mode. The ATtiny85 lacks dedicated SPI hardware but can emulate SPI using the USI module with software clock strobing.
Implementation
The implementation uses the USI control register (USICR) to toggle the clock pin, which triggers automatic bit shifting in hardware.
Frequency Configuration
The ATtiny85 USI lacks hardware prescalers, so frequency is controlled via software delay loops between clock toggles:
SPI Mode Configuration
All 4 SPI modes are supported:
Bit Order Configuration
Both MSB-first (default) and LSB-first bit orders are supported:
LSB-first is implemented via software bit reversal since the USI hardware only supports MSB-first.
References